package eva.savant.business.compras.service

import eva.savant.business.contabilidad.service.TSContabilidad
import eva.savant.business.material.service.TSKardex
import eva.savant.businessobject.cg.Asiento
import eva.savant.businessobject.cg.Documento
import eva.savant.businessobject.cg.Partida
import eva.savant.businessobject.cg.Preasiento
import eva.savant.businessobject.cm.Librocompras
import eva.savant.businessobject.mt.Movimiento
import eva.savant.businessobject.mt.Kardex
import eva.savant.businessobject.mt.Motivo
import eva.savant.businessobject.cm.Compra
import eva.savant.core.service.TSEntity

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Repository

@Repository(value = 'tsCompra')
class TSCompraImpl extends TSEntity implements TSCompra{

  @Autowired
  TSKardex tsKardex

  @Autowired
  TSContabilidad tsContabilidad

  public Compra save(Compra c) throws Exception {

    if(c.lsCompraDetalle.size() < 1) { throw new Exception ('El detalle productos esta vacio') }


    sociedadId= c.sociedadId


    for(x in c.lsCompraDetalle) {

    x.compra = c

    x.operacionId= c.operacionId

    x.sociedadId= c.sociedadId

    x.usuarioId= c.usuarioId  }


    def m= tsKardex.saveInKardex(buildMovimiento(c,TSKardex.INGRESO))

    c= merge(c); updDocumento(c); updAsiento(c)

    m.documento= c.id; merge(m)

    return c
  }

  public Boolean delete(Compra c) throws Exception {

    if(c.lsCompraDetalle.size() < 1) { throw new Exception ('El detalle productos esta vacio') }


    sociedadId= c.sociedadId

    c.operacionId= BAJA


    tsKardex.saveInKardex(buildMovimiento(c,TSKardex.EGRESO))

    return merge(c)
  }

  public Movimiento buildMovimiento(Compra c, String type) {

    def m= new Movimiento()

    m.almacenero= c.almacenero

    m.motivo= get(Motivo.class,TSKardex.COMPRA)

    m.fecha= c.fecha

    m.tipo= type

    m.operacionId= ALTA

    m.sociedadId= c.sociedadId

    m.usuarioId= c.usuarioId

    m.lsKardex= new ArrayList<Kardex>()


    for(x in c.lsCompraDetalle) {

    def k= new Kardex()

    k.almacen        = c.almacen

    k.material       = x.material

    k.persona        = c.proveedor.persona

    k.entradaCantidad= m.tipo.equals(TSKardex.INGRESO)? x.cantidad : null

    k.entradaCosto   = m.tipo.equals(TSKardex.INGRESO)? x.precio   : null

    k.entradaValor   = m.tipo.equals(TSKardex.INGRESO)? k.entradaCantidad * k.entradaCosto : null

    k.salidaCantidad = m.tipo.equals( TSKardex.EGRESO)? x.cantidad : null

    m.lsKardex.add k }


    return m
  }

  public Librocompras mergeLibroCompra(Librocompras libro) throws Exception {

    return merge(libro)
  }

  public Documento updDocumento(Compra c) throws Exception {

    def d= new Documento()

    d.persona= c.proveedor.persona

    d.referencia= c.id + ''

    d.descripcion= 'Compra'

    d.importe= c.importe

    d.creacion= c.fecha

    d.vencimiento= d.creacion

    d.tipo= 'CXP'

    d.operacionId= c.operacionId

    d.sociedadId= c.sociedadId

    d.usuarioId= c.usuarioId

    return tsContabilidad.mergeDocumento(d)
  }

  public Asiento updAsiento(Compra c) throws Exception {

    def pr= get(Preasiento.class,PREASIENTO_COMPRA_CRED)


    def x= new Asiento()

    x.tipo       = pr.tipo

    x.fecha      = c.fecha

    x.detalle    = 'Por compras segun facturas'

    x.importe    = c.importe

    x.referencia = 'COMPRA ' + c.id

    x.operacionId= c.operacionId

    x.sociedadId = c.sociedadId

    x.usuarioId  = c.usuarioId

    x.lsPartida= new ArrayList<Partida>()


    pr.lsPreasientoDetalle.each { println 'preasiento compra cuenta: '+it.cuenta.nombre

    def p= new Partida()

    p.cuenta= it.cuenta

    p.debe  = it.grupo.equalsIgnoreCase('DEBE')?  (it.porcentaje/100) * x.importe : 0

    p.haber = it.grupo.equalsIgnoreCase('HABER')? (it.porcentaje/100) * x.importe : 0


    x.lsPartida.add p }


    return tsContabilidad.mergeAsiento(x)
  }


  public Asiento updAsiento2(Compra c) throws Exception {

    def pr= get(Preasiento.class,PREASIENTO_PAGO_CRED)


    def x= new Asiento()

    x.tipo       = pr.tipo

    x.fecha      = c.fecha

    x.detalle    = 'Por compras segun facturas'

    x.importe    = c.importe

    x.referencia = 'COMPRA ' + c.id

    x.operacionId= c.operacionId

    x.sociedadId = c.sociedadId

    x.usuarioId  = c.usuarioId

    x.lsPartida= new ArrayList<Partida>()


    pr.lsPreasientoDetalle.each { println 'preasiento compra cuenta: '+it.cuenta.nombre

        def p= new Partida()

        p.cuenta= it.cuenta

        p.debe  = it.grupo.equalsIgnoreCase('DEBE')?  (it.porcentaje/100) * x.importe : 0

        p.haber = it.grupo.equalsIgnoreCase('HABER')? (it.porcentaje/100) * x.importe : 0


        x.lsPartida.add p }


    return tsContabilidad.mergeAsiento(x)
  }

}
